/**
 * Project pro_con
 * @author lwj
 */


#include "ProductQueue.h"
#include <time.h>
using std::unique_lock;
/**
 * ProductQueue implementation
 */

ProductQueue::ProductQueue(std::size_t size)
:_que()
,_capacity(size)
,_mux()
,_nopro()
,_fullpro()
{

}

ProductQueue::~ProductQueue() {

}


/**
 * @return bool
 */
bool ProductQueue::empty() {

    return _que.size() == 0; 
}

/**
 * @return bool
 */
bool ProductQueue::full() {
    return _capacity == _que.size();
}

size_t ProductQueue::getSize()
{
    return _que.size();
}

/**
 * @return void
 */
int ProductQueue::pop() {
    //拿到锁
    unique_lock<mutex> ul(_mux);
    //判空,注意使用while避免虚假唤醒
    while(empty())
    {
        //睡觉
       _nopro.wait(ul); 
    }
    //有了产品，进行消费
    int temp = _que.front();
    _que.pop();
    //唤醒生产者
    _fullpro.notify_one();
    //归还锁
    return temp;
}

/**
 * @param num
 * @return void
 */
void ProductQueue::push(int & num) {
    unique_lock<mutex> ul(_mux);
    while(full())
    {
        _fullpro.wait(ul);
    }
    _que.push(num);
    _nopro.notify_one();
    //释放锁，离开作用域即释放
    return;
}


